package idv.arthur.prac;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.ISVNReporter;
import org.tmatesoft.svn.core.io.ISVNReporterBaton;
import org.tmatesoft.svn.core.io.ISVNWorkspaceMediator;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;
import org.tmatesoft.svn.core.wc.SVNClientManager;


 class MyISVNReporter implements ISVNReporter {
	@Override
	public void setPath(String path, String lockToken, long revision,
			boolean startEmpty) throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override 
	public void setPath(String path, String lockToken, long revision,
			SVNDepth depth, boolean startEmpty) throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void deletePath(String path) throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void linkPath(SVNURL url, String path, String lockToken,
			long revision, boolean startEmpty) throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void linkPath(SVNURL url, String path, String lockToken,
			long revision, SVNDepth depth, boolean startEmpty)
			throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void finishReport() throws SVNException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void abortReport() throws SVNException {
		// TODO Auto-generated method stub
		
	}
 }
 class MyISVNReporterBaton implements ISVNReporterBaton {
		@Override
		public void report(ISVNReporter reporter) throws SVNException {
			reporter.setPath("", null, 1, SVNDepth.INFINITY, false);
    reporter.finishReport(); 
		}
	}
 
public class SVNCommitEditorPractice {

	/**
	 * 創建時間：2012/10/30 上午10:51:29 創建人員：郭啟揚 (842297)
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		DefaultSVNOptions options = new DefaultSVNOptions();
		SVNClientManager manager = SVNClientManager.newInstance(options,"Arthur","abcd1234"); //如果需要用戶名密碼
		String tarUrl = "http://arthur-pc.cht.com.tw/svn/AirForce/";	//欲寫入的路徑
		String baseChecksum = "";
		SVNRepository tarRepo = null;
		ISVNEditor editor = null;
		 SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator();
		
		 String logMessage = "your commit log message";	//在Commit時送出的Message
		
		
		SVNCommitInfo info = null;
		try {
			File file = new File( "d:/Eclipse.txt" );
			InputStream is = SVNFileUtil.openFileForReading(file);
			
			SVNURL tarRepoBaseUrl = SVNURL.parseURIEncoded(tarUrl); // 傳入svn地址
			
			/** H-目的地Repo要做的事 **/
			tarRepo = manager.getRepositoryPool().createRepository(tarRepoBaseUrl,true);
			/** T-目的地Repo要做的事 **/
			
			String fileName = "ORWCP.war";
			//String fileName = String.valueOf(System.currentTimeMillis());
			SVNNodeKind nodeKind = tarRepo.checkPath( fileName /* 相對於根目錄的路徑 */ ,  -1 );
			 /** ISVNEditor 實體 **/
			editor = tarRepo.getCommitEditor(logMessage, new CommitMediator());
			editor.openRoot(-1);
			
			if ( nodeKind == SVNNodeKind.NONE ) {
				System.out.println( "檔案尚未存在可以新增!\n");
			    editor.addFile(fileName, null /** 從另一個"路逕" 複製過來 **/, -1 /** 另一個路逕上的那個版本 **/);
			} else {
			    System.out.println( "已存在!!  該使用更新!" );
			    editor.openFile(fileName, -1);	/** -1 或 正確的版本都可以 **/
			}	// end of else
			editor.applyTextDelta(fileName, null); 
			baseChecksum = deltaGenerator.sendDelta(fileName, is, editor, true);
		    System.out.println("MD5："+baseChecksum);
			is.close();
		    editor.textDeltaEnd(fileName);
		    editor.closeFile(fileName, baseChecksum);
		    info =  editor.closeEdit();
			System.out.println("getNewRevision："+info.getNewRevision());
		    System.out.println("getAuthor："+info.getAuthor());
		    System.out.println("執行完畢！");
		    
		} catch (SVNException e) {
			System.out.println(errProcess(e));
		} catch (Exception e) {
			System.out.println(errProcess(e));
		}
	}

	public static class CommitMediator implements ISVNWorkspaceMediator {
		private Map myTmpStorages = new HashMap();

		/*
		 * This may be implemented to get properties from '.svn/wcprops'
		 */
		public SVNPropertyValue getWorkspaceProperty(String path, String name)
				throws SVNException {
			return null;
		}

		/*
		 * This may be implemented to set properties in '.svn/wcprops'
		 */
		public void setWorkspaceProperty(String path, String name, String value)
				throws SVNException {
		}

		/*
		 * Creates a temporary file delta storage. id will be used as the
		 * temporary storage identifier. Returns an OutputStream to write the
		 * delta data into the temporary storage.
		 */
		public OutputStream createTemporaryLocation(String path, Object id)
				throws IOException {
			ByteArrayOutputStream tempStorageOS = new ByteArrayOutputStream();
			myTmpStorages.put(id, tempStorageOS);
			return tempStorageOS;
		}

		/*
		 * Returns an InputStream of the temporary file delta storage identified
		 * by id to read the delta.
		 */
		public InputStream getTemporaryLocation(Object id) throws IOException {
			return new ByteArrayInputStream(
					((ByteArrayOutputStream) myTmpStorages.get(id))
							.toByteArray());
		}

		/*
		 * Gets the length of the delta that was written to the temporary
		 * storage identified by id.
		 */
		public long getLength(Object id) throws IOException {
			ByteArrayOutputStream tempStorageOS = (ByteArrayOutputStream) myTmpStorages
					.get(id);
			if (tempStorageOS != null) {
				return tempStorageOS.size();
			}
			return 0;
		}

		/*
		 * Deletes the temporary file delta storage identified by id.
		 */
		public void deleteTemporaryLocation(Object id) {
			myTmpStorages.remove(id);
		}

		@Override
		public void setWorkspaceProperty(String path, String name,
				SVNPropertyValue value) throws SVNException {
		}
	}

	private static String errProcess (Exception e) {
		String mes = "";
	    mes += e.toString() + "\n\n";
		for (int i=0; i<e.getStackTrace().length;i++) {
			mes += "檔案名稱："+e.getStackTrace()[i].getFileName() + "\n";
			mes += "所在行數："+e.getStackTrace()[i].getLineNumber() + "\n";
			mes += "方法名稱："+e.getStackTrace()[i].getMethodName() + "\n";
			mes += "類別名稱："+e.getStackTrace()[i].getClassName() + "\n\n";
		}
		
		return mes;
	}
}
